package _java8新特性;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * https://www.wdbyte.com/2019/11/jdk/jdk8-optional/#_5-optional-%E9%BB%98%E8%AE%A4%E5%80%BC
 *
 * 总结：Optional 创建存值、判断、取值
 *
 * 1、三种创建 Optional 对象的方法
 *      Optional.of()
 *      Optional.ofEmpty()
 *      Optional.ofNullable(null)
 *
 * 2、判断是否为空
 *      .isPresent()    // 是否存在
 *
 * 3、获取 Optional 中的原始值
 *      .get()          // 如果没有值，会抛异常
 * 3、获取 Optional 的默认值
 *      .orElse()
 *      .orElseGet()
 * 3、获取 Optional 的异常值（没有值的话）
 *      .orThrow()
 *
 * 4、Optional 类的函数式接口
 *      .filter()
 *      .map()
 *      .flatMap()
 *
 */
public class LN_01_Optional {

    // 三种创建 Optional 对象的方法
    private Optional<String> stringOptional = Optional.of("hello world");
    private Optional<String> emptyOptional = Optional.empty();
    private Optional<Object> nullOptional = Optional.ofNullable(null);

    @Test
    public void isPresentOption() {
        System.out.println(stringOptional.isPresent()); // true
        System.out.println(emptyOptional.isPresent());  // false
        System.out.println(nullOptional.isPresent());   // false

        List<Integer> list = new ArrayList<>();
        Optional<List<Integer>> optionalIntegers = Optional.ofNullable(list);
        System.out.println(optionalIntegers.isPresent()); // true
        list = null;
        Optional<List<Integer>> optionalInteger = Optional.ofNullable(list);
        System.out.println(optionalInteger.isPresent()); // false
    }

    @Test
    public void getValueOption() {
        System.out.println(stringOptional.get());   // hello world
        System.out.println(emptyOptional.get());    // NoSuchElementException: No value present
        System.out.println(nullOptional.get());     // NoSuchElementException: No value present
    }

    @Test
    public void getDefaultValueOption() throws Exception {
        String str = stringOptional.get();
        System.out.println(str);
        String str1 = stringOptional.orElse("UNKNOWN");
        System.out.println(str1);       // hello world

        String str2 = emptyOptional.orElse("UNKNOWN");
        System.out.println(str2);       // UNKNOWN
        String str3 = emptyOptional.orElseGet( ()->"UNKNOWN" );
        System.out.println(str3);
        String str5 = emptyOptional.orElseThrow( ()->new Exception("没有值") );
    }

    @Test
    public void functionalOption() throws Exception {
        Optional<Integer> integerOptional = Optional.of(45);
        integerOptional
                .filter(num -> num==22)
                .ifPresent((num)-> System.out.println(num));
        integerOptional
                .filter(num -> num==45).
                ifPresent(System.out::println);

        // lambda
        Optional<Integer> integerOptional1 = Optional.of(45678);
        integerOptional1
                .map(num -> String.valueOf(num))
                .map(str -> str.length())
                .ifPresent(ans -> System.out.println(ans));
        // 方法引用
        integerOptional1
                .map(String::valueOf)
                .map(String::length)
                .ifPresent(System.out::println);
    }
}
